#include <linux/socket.h>
#include <linux/netlink.h>
#include <net/sock.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>

#define NETLINK_TEST 17
#define MAX_PAYLOAD 1024

struct sock *nl_sk = NULL;

void nl_data_ready (struct sock *sk, int len)
{
    wake_up_interruptible(sk->sk_sleep);
}

void netlink_test()
{
    struct sk_buff *skb = NULL;
    struct nlmsghdr *nlh = NULL;
    int err;
    unsigned long pid;

    nl_sk = netlink_kernel_create(NETLINK_TEST, 0, nl_data_ready, NULL, THIS_MODULE);
    /* wait for message coming down from user-space */
    skb = skb_recv_datagram(nl_sk, 0, 0, &err);

    nlh = (struct nlmsghdr *)skb->data;
    printk("%s: received netlink message payload:%s\n",
        __FUNCTION__, (char *)NLMSG_DATA(nlh));

    pid = nlh->nlmsg_pid; /*pid of sending process */
    NETLINK_CB(skb).pid = pid;
    NETLINK_CB(skb).dst_group = 0;  /* unicast */
    netlink_unicast(nl_sk, skb, pid, MSG_DONTWAIT);
    sock_release(nl_sk->sk_socket);
}   

static int __init hello_start(void)
{
    printk("Loading netlink demo module...\n");

    netlink_test();
    return 0;
}

static void  hello_end(void)
{
    printk("Exiting netlink demo module...\n");
}

module_init(hello_start);
module_exit(hello_end);

MODULE_LICENSE("GPL");

